package cn.edu.wtbu.wtbu_music_server.controller;

import cn.edu.wtbu.wtbu_music_server.dto.R;
import cn.edu.wtbu.wtbu_music_server.entity.Album;
import cn.edu.wtbu.wtbu_music_server.entity.List;
import cn.edu.wtbu.wtbu_music_server.entity.Music;
import cn.edu.wtbu.wtbu_music_server.entity.Musiclist;
import cn.edu.wtbu.wtbu_music_server.service.AlbumService;
import cn.edu.wtbu.wtbu_music_server.service.ListService;
import cn.edu.wtbu.wtbu_music_server.service.MusicService;
import cn.edu.wtbu.wtbu_music_server.service.MusiclistService;
import cn.edu.wtbu.wtbu_music_server.service.impl.ListServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 歌单模块业务功能接口：
 * 1. 歌单创建
 * 2. 歌单修改
 * 3. 向歌单中添加歌曲
 * 4. 歌单详情查看
 * 5. 删除歌单中歌曲
 * 6. 删除歌单
 */
@Tag(name = "歌单接口",description = "歌单模块相关的Rest接口")
@RequestMapping("/musiclist")
@RestController
public class MusiclistController  extends BaseController{

    /**
     * 自动注入ListService, 用于处理与歌单相关的业务逻辑。
     */
    @Autowired
    private ListService listService;

    /**
     * 自动注入MusiclistService, 用于处理与歌单与歌曲关联的业务逻辑。
     */
    @Autowired
    private MusiclistService musiclistService;

    /**
     * 自动注入MusicService, 用于处理与音乐相关的业务逻辑。
     */
    @Autowired
    private MusicService musicService;

    /**
     * 自动注入AlbumService, 用于处理与专辑相关的业务逻辑。
     */
    @Autowired
    private AlbumService albumService;


    /**
     * 根据提供的歌单信息创建歌单
     */
    @Operation(summary = "创建歌单",description = "根据提供的歌单对象创建歌单")
    @PostMapping("/create")
    public R create(@RequestBody List list) {
        //判断当前歌单对象是否存在
        if (exists(list.getName())) {
            return R.fail().setMsg("歌单已存在");
        }
        boolean b = listService.save(list);
        return b ? R.ok().setMsg("创建成功") : R.fail().setMsg("创建失败");
    }

    /**
     * 根据歌单id修改歌单信息
     */
    @Operation(summary = "修改歌单",description = "根据提供的歌单对象修改歌单信息")
    @PutMapping("/update")
    public R update(@RequestBody List list) {
        if (Objects.isNull(list.getId())) {
            return R.fail().setMsg("歌单id不能为空");
        }
        if (exists(list.getName())) {
            return R.fail().setMsg("歌单已存在");
        }
        boolean b = listService.updateById(list);
        return b ? R.ok().setMsg("修改成功") : R.fail().setMsg("修改失败");
    }

    /**
     * 向歌单中添加歌曲
     */
    @Operation(summary = "添加歌曲",description = "根据提供的音乐id和歌单id添加歌曲")
    @Parameters({
            @Parameter(name = "mid",description = "音乐id",required = true),
            @Parameter(name = "listid",description = "歌单id",required = true)
    })
    @PostMapping("/add")
    public R add(@RequestParam("mid") Integer mid, @RequestParam("listid") Integer listid) {
        //判断当前歌单中是否存在指定歌曲  select * from musiclist  where mid=? and listid=?
        LambdaQueryWrapper<Musiclist> query = Wrappers.lambdaQuery(Musiclist.class).eq(Musiclist::getMid, mid).eq(Musiclist::getListid, listid);
        if (musiclistService.exists(query)) {
            return R.fail().setMsg("歌单中已存在该歌曲");
        }
        return musiclistService.save(new Musiclist(mid, listid)) ? R.ok().setMsg("添加成功") : R.fail().setMsg("添加失败");
    }

    /**
     * 根据歌单id查询歌单中的歌曲详情（包括歌曲的专辑详情）
     */
    @Operation(summary = "获取歌单信息",description = "根据提供的歌单id查询歌单中的歌曲详情（包括歌曲的专辑详情）")
    @Parameter(name = "id",description = "歌单id",required = true)
    @GetMapping("/info/{id}")
    public R info(@PathVariable("id") Integer id) {
        //根据歌单id查询歌单中所有的歌曲id和歌单关联对象
        java.util.List<Musiclist> list = musiclistService.list(Wrappers.lambdaQuery(Musiclist.class).eq(Musiclist::getListid, id));
        //获取所有的歌曲id
        java.util.List<Integer> ids = list.stream().map(Musiclist::getMid).toList();
        //获取所有歌曲的详情
        java.util.List<Music> musicList = musicService.listByIds(ids);
        //获取所有的专辑id集合(去除重复，因此使用set集合)
        Set<Integer> albumIds = musicList.stream().map(Music::getAid).collect(Collectors.toSet());
        //查询所有的专辑信息
        java.util.List<Album> albumList = albumService.listByIds(albumIds);
        //将专辑id和专辑对象进行映射（包装成Map集合）
        Map<Integer, Album> map = albumList.stream().collect(Collectors.toMap(Album::getId, album -> album));
        //循环遍历所有歌曲，并将歌曲的专辑对象设置给歌曲对象
        musicList.forEach(music -> {
            music.setAlbum(map.get(music.getAid()));
        });
        return R.ok().setData(musicList);
    }

    /**
     * 删除歌单中的指定歌曲  http://127.0.0.1/musiclist/delMusic/1/1
     */
    @Operation(summary = "删除歌曲",description = "根据提供的音乐id和歌单id删除歌单中的歌曲")
    @Parameters({
            @Parameter(name = "mid",description = "音乐id",required = true),
            @Parameter(name = "listid",description = "歌单id",required = true)
    })
    @DeleteMapping("/delMusic/{mid}/{listid}")
    public R delMusic(@PathVariable Integer mid, @PathVariable Integer listid) {
        //根据mid和listid删除歌单中的歌曲
        //构建查询条件包装器
        LambdaQueryWrapper<Musiclist> query = Wrappers.lambdaQuery(Musiclist.class)
                .eq(Musiclist::getMid, mid)
                .eq(Musiclist::getListid, listid);
        //根据条件包装器执行删除操作
        boolean b = musiclistService.remove(query);
        //返回结果
        return b ? R.ok().setMsg("删除成功") : R.fail().setMsg("删除失败");
    }

    /**
     * 删除歌单(包括歌单中的所有歌曲)
     */
    @Operation(summary = "删除歌单",description = "根据提供的歌单id删除歌单(包括歌单中的所有歌曲)")
    @Parameter(name = "id",description = "歌单id",required = true)
    @Transactional  //加入事务
    @DeleteMapping("/delete/{id}")
    public R delete(@PathVariable Integer id) {
        //根据歌单id删除歌单中的所有歌曲
        boolean b = musiclistService.remove(Wrappers.lambdaQuery(Musiclist.class).eq(Musiclist::getListid, id));
        //执行歌单删除
        return listService.removeById(id) ? R.ok().setMsg("删除成功") : R.fail().setMsg("删除失败");
    }

    /**
     * 查询歌单名是否重复
     */
    private boolean exists(String name) {
        //查询歌单名是否重复
        return listService.exists(Wrappers.lambdaQuery(List.class).eq(List::getName, name));
    }

}
